#ifndef INTERPOLATION_HPP
#define INTERPOLATION_HPP
#include "GLHeaders.hpp"
#include "Color.hpp"

enum Interp{
  NEAREST = 0,
  LINEAR = 1,
  CUBIC = 2,
  QUINTIC = 3
};

//////////////////////
//      GLfloat     //
//////////////////////
inline GLfloat NearestInterp(GLfloat x0, GLfloat x1, GLfloat value){
  return ((value < 0.5f)? x0 : x1);
}

// Value must be in [0.0f;1.0f]
inline GLfloat LinearInterp(GLfloat x0, GLfloat x1, GLfloat value){
  return ((1.0f - value)*x0 + value*x1);
}

// Scurve3 : -2*t³+3t²
inline GLfloat CubicInterp(GLfloat x0, GLfloat x1, GLfloat value){
  GLfloat tmp = (value * value * (3.0f - 2.0f * value));
  return ((1.0f - tmp)*x0 + tmp*x1);
}

// Scurve 5 : 6*t⁵-15*t⁴+10*t³
inline GLfloat QuinticInterp(GLfloat x0, GLfloat x1, GLfloat value){
  GLfloat t3 = value * value * value;
  GLfloat t4 = t3 * value;
  GLfloat t5 = t4 * value;
  GLfloat tmp = ((6.0f * t5) - (15.0f * t4) + (10.0f * t3));
  return ((1.0f - tmp)*x0 + tmp*x1);
}

//////////////////////
//      Color       //
//////////////////////
inline Color NearestInterp(const Color &c0, const Color &c1, GLfloat value){
  return ((value < 0.5f)? c0 : c1);
}

// Value must be in [0.0f;1.0f]
inline Color LinearInterp(const Color &c0, const Color &c1, GLfloat value){
  return ((1.0f - value)*c0 + value*c1);
}

// Scurve3 : -2*t³+3t²
inline Color CubicInterp(const Color &c0, const Color &c1, GLfloat value){
  GLfloat tmp = (value * value * (3.0f - 2.0f * value));
  return ((1.0f - tmp)*c0 + tmp*c1);
}

// Scurve 5 : 6*t⁵-15*t⁴+10*t³
inline Color QuinticInterp(const Color &c0, const Color &c1, GLfloat value){
  GLfloat t3 = value * value * value;
  GLfloat t4 = t3 * value;
  GLfloat t5 = t4 * value;
  GLfloat tmp = ((6.0f * t5) - (15.0f * t4) + (10.0f * t3));
  return ((1.0f - tmp)*c0 + tmp*c1);
}

#endif
